package com.htfyun.roobofactory.factorytest;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.TextView;

import com.htfyun.roobofactory.BaseActivity;
import com.htfyun.roobofactory.R;
import com.htfyun.roobofactory.config.RooboBuildConfig;
import com.htfyun.roobofactory.htfyunUtils.ExecuteCommand;
import com.htfyun.roobofactory.rooboUtils.IflytekInit;
import com.htfyun.roobofactory.rooboUtils.RooboEngine;
import com.htfyun.roobofactory.rooboUtils.XunFeiWakeUpTranslator;
import com.htfyun.roobofactory.utils.PermissionManager;

import java.io.IOException;
import java.lang.ref.WeakReference;

/**
 * Created by sst on 2018/7/10.
 */

public class WakeupTestActivity extends BaseActivity {

    public static final int SUCCESS_WAKEUP_COUNT = 7;
    public static final int WAKEUP_SCORE = -15;

    private Button btnPass;
    private Button btnFail;

    private TextView txtStatus;
    private TextView txtCount;
    private TextView txtInfo;

    private TextView txtMusicDuration;
    private SeekBar seekBar;
    private int musicDurationSecond;
    private int curMusicDurationSecond;

    private MediaPlayer mediaPlayer;
    private AudioManager audioManager = null;

    private RooboEngine rooboEngine;

    private Handler mHandler;
    private Context mContext;

    private boolean isMusicStarted;

    private int wakeupCount = 0;
    private boolean canWakeup = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_factorytest_wakeup);

        btnPass = (Button) findViewById(R.id.btnPass);
        btnFail = (Button) findViewById(R.id.btnFail);
        btnPass.setOnClickListener(onPassOrFailClickListener);
        btnFail.setOnClickListener(onPassOrFailClickListener);

        btnPass.setVisibility(RooboBuildConfig.FT_ADD_PASS_BTN ? View.VISIBLE : View.GONE);

        txtMusicDuration = (TextView) findViewById(R.id.txtMusicDuration);
        seekBar = (SeekBar) findViewById(R.id.seekBar);
        txtMusicDuration.setVisibility(View.GONE);
        seekBar.setVisibility(View.GONE);

        txtStatus = (TextView) findViewById(R.id.txtStatus);
        txtCount = (TextView) findViewById(R.id.txtCount);
        txtInfo = (TextView) findViewById(R.id.txtInfo);

        txtInfo.setVisibility(View.INVISIBLE);

        txtCount.setText(getString(R.string.wakeup_success_count, wakeupCount, (SUCCESS_WAKEUP_COUNT - wakeupCount)));
        txtStatus.setText(getString(R.string.wakeup_test_status, getString(R.string.wakeup_status_start_recognition)));

        mContext = this;
        mHandler = new MyHandler(this);

        audioManager = getSystemService(AudioManager.class);
        int currentVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
        int maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
        Log.d(TAG, "currentVolume: " + currentVolume + " maxVolume: " + maxVolume);

        audioManager.setStreamVolume(AudioManager.STREAM_MUSIC,maxVolume,0);
        int currentVolume1 = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
        Log.d(TAG, "currentVolume1: " + currentVolume1 + " maxVolume: " + maxVolume);

        executeShellCommand(ShellCommandEnum.set_output);

    }

    @Override
    protected void onResume() {
        super.onResume();
        initPermission();
    }

    @Override
    protected void onPause() {
        super.onPause();

        if(mHandler.hasMessages(MSG_START)){
            mHandler.removeMessages(MSG_START);
        }
        if(mHandler.hasMessages(MSG_MUSIC)){
            mHandler.removeMessages(MSG_MUSIC);
        }

        destroyIflytekVoiceRecognition();
        stopPlayMusic();

    }


    private void initPermission() {

        if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED
                || ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
                || ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {

            //同时申请多个权限
            PermissionManager.getInstance(getApplicationContext()).execute(this,
                    Manifest.permission.RECORD_AUDIO,
                    Manifest.permission.READ_EXTERNAL_STORAGE,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE

                    );

        } else {

            startRecognition();

        }


    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        PermissionManager.getInstance(getApplicationContext()).
                onRequestPermissionsResult(requestCode, permissions, grantResults);

        Log.e(TAG, "wakeup ~~~~~~~~~~~~~~onRequestPermissionsResult");

        startRecognition();


    }

    private View.OnClickListener onPassOrFailClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (v == btnPass) {

                setResult(RESULT_OK);
                ActivityCompat.finishAfterTransition(getActivity());

            } else if (v == btnFail) {

                setResult(RESULT_CANCELED);
                ActivityCompat.finishAfterTransition(getActivity());

            }
        }
    };


    private void startRecognition() {
        if(!mHandler.hasMessages(MSG_START)){
            Message msg = mHandler.obtainMessage(MSG_START);
            mHandler.sendMessageDelayed(msg,DELAY_START);
        }
    }

    private void initIflytekVoiceRecognition() {

        IflytekInit.init(mContext.getApplicationContext());
        rooboEngine = RooboEngine.getInstance();
        rooboEngine.setScore(WAKEUP_SCORE);
        rooboEngine.setWakeupListener(new WakeupListener());

        canWakeup = true;
        isMusicStarted = false;

        txtStatus.setText(getString(R.string.wakeup_test_status, getString(R.string.wakeup_status_doing)));
    }

    private void destroyIflytekVoiceRecognition() {

        if (rooboEngine != null) {
            rooboEngine.destroy();
            rooboEngine = null;
        }
    }

    private void handleRecognition() {

        txtCount.setText(getString(R.string.wakeup_success_count, wakeupCount, (SUCCESS_WAKEUP_COUNT - wakeupCount)));

        if (wakeupCount >= SUCCESS_WAKEUP_COUNT) {
            stopPlayMusic();
            canWakeup = false;
            txtStatus.setText(getString(R.string.wakeup_test_status, getString(R.string.test_result_pass)));

            startAutoPass(R.string.test_wakeup_pass);

        } else if (!canWakeup) {
            txtStatus.setText(getString(R.string.wakeup_test_status, getString(R.string.test_result_fail)));
        }
    }

    private void startPlayMusic() {
        if (!isMusicStarted) {
            Log.e(TAG, "start app .music");
            isMusicStarted = true;
            wakeupCount = 0;

            executeShellCommand(ShellCommandEnum.set_micboost);

            mediaPlayer = MediaPlayer.create(this, R.raw.music_little_apple);
            mediaPlayer.setOnCompletionListener(new PlayMusicCompleteListener());
            mediaPlayer.setVolume(0.7f, 0.7f);
            mediaPlayer.start();//开始音频的播放

            musicDurationSecond = mediaPlayer.getDuration() / 1000;
            int sec = musicDurationSecond;
            txtInfo.setText(getString(R.string.wakeup_info, sec, SUCCESS_WAKEUP_COUNT));
            txtInfo.setVisibility(View.VISIBLE);

            curMusicDurationSecond = 0;

            txtMusicDuration.setVisibility(View.VISIBLE);
            seekBar.setVisibility(View.VISIBLE);
            seekBar.setMax(musicDurationSecond);
            seekBar.setClickable(false);
            seekBar.setEnabled(false);
            seekBar.setSelected(false);
            seekBar.setFocusable(false);

            updateUIForMusic();
        } else {
            Log.e(TAG, "music has started");
        }
    }

    private void stopPlayMusic() {
        if (mediaPlayer != null) {
            mediaPlayer.stop();//停止音频的播放
            mediaPlayer.release();
            mediaPlayer = null;
        }
    }

    private void updateUIForMusic() {

        txtMusicDuration.setText(curMusicDurationSecond +  " / " + musicDurationSecond);
        seekBar.setProgress(curMusicDurationSecond);
        curMusicDurationSecond++;

        mHandler.sendEmptyMessageDelayed(MSG_MUSIC, PERIOD_MUSIC);
    }

    private static final int MSG_START = 0;
    private static final int DELAY_START = 2 * 1000;
    private static final int MSG_MUSIC = 1;
    private static final int PERIOD_MUSIC = 1 * 1000;
    private final static class MyHandler extends Handler {

        private WeakReference<WakeupTestActivity> reference;

        public MyHandler(WakeupTestActivity activity) {
            reference = new WeakReference<WakeupTestActivity>(activity);
        }

        @Override
        public void handleMessage(Message msg) {

            WakeupTestActivity activity = reference.get();
            if (activity == null) {
                return;
            }

            if (msg.what == MSG_START) {
                activity.initIflytekVoiceRecognition();
            } else if (msg.what == MSG_MUSIC) {

                activity.updateUIForMusic();
            }
        }
    }

    private class WakeupListener implements XunFeiWakeUpTranslator.WakeupListener {
        @Override
        public void onWakeUp(String json) {

            if (!canWakeup) {
                return;
            }

            startPlayMusic();

            wakeupCount++;

            handleRecognition();
        }
    }

    public class PlayMusicCompleteListener implements MediaPlayer.OnCompletionListener {
        public void onCompletion(MediaPlayer mp) {

            Log.e(TAG, "PlayMusicCompleteListener over");

            canWakeup = false;
            handleRecognition();
        }
    }

    private void executeShellCommand(ShellCommandEnum shellCommandEnum) {
        try {

            ExecuteCommand.execCommand(shellCommandEnum.getCmd());

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    private enum ShellCommandEnum {

        set_micboost("system/bin/cxdish_normal set-micboost 12"),
        set_output("system/bin/cxdish_normal set-output 0,0"),

        ;
        private final String cmd;

        ShellCommandEnum(String cmd) {
            this.cmd = cmd;
        }

        public String getCmd() {
            return cmd;
        }
    }
}
